import { defineGlobalProperty, generateId, interceptRoom } from '@/ayaka'
import { SquadTask } from '../types'
import { BodyPartArrayType } from '@/utils/common'
import SpawnController, { getCreeps } from '@/modules/structures/spawn'
import { CreepRoles, SpawnTask } from '@/modules/structures/spawn/types'
import { squadWork } from './squadWork'
import { CreepBoostData } from '@/modules/structures/lab/types'
import { ResourcePartMap } from '@/utils/constants'

export default class SquadController {
    public static run(room: MyRoom) {
        const { tasks } = SquadController.getMemory(room)
        tasks.forEach((task) => SquadController.execute(room, task))
    }

    /**
     * 执行任务
     */
    public static execute(room: MyRoom, task: SquadTask) {
        const { squadMember } = task

        const squadMembers = getCreeps(room, squadMember)
        if (squadMembers.length === 4) {
            task.spawnComplete = true
        } else if (!task.spawnComplete) {
            SquadController.spawnSquadMember(room, task)
        } else if (!squadMembers.length) {
            SquadController.delete(room, task.id)
            return
        }

        squadWork(squadMembers, task)
    }

    /**
     * 获取 memory
     */
    public static getMemory(room: MyRoom) {
        if (!room.memory.war.squad) {
            room.memory.war.squad = {
                tasks: [],
            }
        }
        return room.memory.war.squad
    }

    /**
     * 孵化四人小队成员
     */
    public static spawnSquadMember(room: MyRoom, task: SquadTask) {
        if (SpawnController.searchSpawnTaskByRole(room, CreepRoles.squadMember).length) return
        const isAttacker = task.squadMember.length < 2
        const body = isAttacker ? task.attackerBody : task.healerBody
        const boostResource = isAttacker ? task.attackerBoost : task.healerBoost
        const spawnTask: SpawnTask = {
            role: CreepRoles.squadMember,
            body,
            memory: {},
        }
        if (boostResource?.length) {
            spawnTask.memory!.boost = {
                data: boostResource.reduce((acc, cur) => {
                    acc[ResourcePartMap[cur]] = {
                        type: cur,
                        require: 50,
                        amount: 0,
                    }
                    return acc
                }, {} as CreepBoostData),
            }
        }
        const creepName = SpawnController.addSpawnTask(room, spawnTask)
        if (!creepName) return
        task.squadMember.push(creepName)
    }

    /**
     * 发布指定房间的四人小队任务
     */
    public static publish(room: MyRoom, task: SquadTask) {
        const memory = SquadController.getMemory(room)
        memory.tasks.push(task)
    }

    /**
     * 手动发布四人小队任务
     */
    @interceptRoom()
    public static add(
        myRoomName: string,
        targetRoomName: string,
        attackerBody: BodyPartArrayType,
        healerBody: BodyPartArrayType,
        attackerBoost: MineralBoostConstant[] = [],
        healerBoost: MineralBoostConstant[] = [],
        name?: string,
    ) {
        const task: SquadTask = {
            id: generateId(8),
            roomName: targetRoomName,
            squadMember: [],
            attackerBody,
            healerBody,
            attackerBoost,
            healerBoost,
        }
        if (name) {
            task.name = name
        }
        SquadController.publish(Game.rooms[myRoomName] as MyRoom, task)
        return `四人小队任务 ${myRoomName} -> ${targetRoomName} 发布成功`
    }

    /**
     * 删除指定 id 的四人小队任务
     */
    public static delete(room: MyRoom, id: string) {
        const memory = SquadController.getMemory(room)
        memory.tasks = memory.tasks.filter((task) => task.id !== id)
    }
}

defineGlobalProperty('Squad', {
    value: SquadController,
})
